﻿using ServerBase.Config;
using System.Reflection;

namespace SvGame.Logic;

public static partial class GameLogic
{
    public static List<string> GetLimbs(this IRole me)
    {
        List<string> limbs = new();
        if (ConfRaceExt.TryGetValue(me.Race, out var conf)) 
        {
            limbs = conf.SettBase.Limbs;
        }
        else
        {
            limbs.Add("身体");
        }
        return limbs;
    }
    public static string GetLimb(this IRole me)
    {
        return me.GetLimbs().RandomSingle();
    }
    public static void ReceiveHealKee(this IRole me, int heal)
    {
        me.StatusCur.Kee = Math.Min(me.StatusCur.Kee + heal, me.StatusEff.Kee);
    }
    public static void ReceiveCuringKee(this IRole me, int heal)
    {
        me.StatusEff.Kee = Math.Min(me.StatusEff.Kee + heal, me.StatusMax.Kee);
    }
    public static void ReceiveHealSen(this IRole me, int heal)
    {
        me.StatusCur.Sen = Math.Min(me.StatusCur.Sen + heal, me.StatusEff.Sen);
    }
    public static void ReceiveCuringSen(this IRole me, int heal)
    {
        me.StatusEff.Sen = Math.Min(me.StatusEff.Sen + heal, me.StatusMax.Sen);
    }
    public static void ReceiveDamageKee(this IRole me, int damage, IRole who)
    {
        me.Comb.LastDamageFrom = who;

        var value = me.StatusCur.Kee - damage;
        if (value < 0) 
        { 
            value = -1;
        }
        me.StatusCur.Kee = value;
    }
    public static void ReceiveWoundKee(this IRole me, int damage, IRole who)
    {
        me.Comb.LastDamageFrom = who;

        var value = me.StatusEff.Kee - damage;
        if (value < 0)
        {
            value = -1;
        }
        me.StatusEff.Kee = value;
    }
    public static void ReceiveDamageSen(this IRole me, int damage, IRole who)
    {
        me.Comb.LastDamageFrom = who;

        var value = me.StatusCur.Sen - damage;
        if (value < 0)
        {
            value = -1;
        }
        me.StatusCur.Sen = value;
    }
    public static void ReceiveWoundSen(this IRole me, int damage, IRole who)
    {
        me.Comb.LastDamageFrom = who;

        var value = me.StatusEff.Sen - damage;
        if (value < 0)
        {
            value = -1;
        }
        me.StatusEff.Sen = value;
    }
    public static string DamageMessage(int damage, string damageType = "伤害")
    {
        if (damage <= 0) 
        {
            return "结果没有造成任何伤害。";
        }
        string desc = "";
        if (!ConfCbtDamageExt.ContainsKey(damageType)) 
        {
            damageType = "伤害";
        }
        if (ConfCbtDamageExt.TryGetValue(damageType, out var list))
        {
            foreach ( var item in list)
            {
                if (damage > item.Vmin && damage <= item.Vmax)
                {
                    desc = item.Desc;
                    break;
                }
            }
        }
        if (desc.IsNullOrEmpty())
        {
            desc = $"造成{damage}点{damageType}";
        }
        return desc;
    }
    public static void ReportStatusKee(IRole me, bool effective = false)
    {
        string desc;
        if (effective)
        {
            desc = DescEffKee(me.StatusEff.Kee, me.StatusMax.Kee);
        }
        else
        {
            desc = DescEffKee(me.StatusCur.Kee, me.StatusMax.Kee);
        }
        if (!desc.IsNullOrEmpty())
        {
            MessageVision($"( $N{desc} )", me);
        }
    }
    public static void ReportStatusSen(IRole me)
    {
        string desc;
        desc = DescSen(me.StatusCur.Sen, me.StatusMax.Sen);
        if (!desc.IsNullOrEmpty())
        {
            MessageVision($"( $N{desc} )", me);
        }
    }
    public static void ApplyDamage(IRole me, IRole opp, int damage, EPerformDamageType damage_type, string msg_hit)
    {
        int damage_qi, damage_shen;
        if (damage_type == EPerformDamageType.Kee)
        {
            damage_qi = damage;
            damage_shen = 0;
        }
        else if (damage_type == EPerformDamageType.Sen)
        {
            damage_qi = 0;
            damage_shen = damage;
        }
        else
        {
            damage_qi = damage;
            damage_shen = damage;
        }
        MessageVision(msg_hit, me, opp);

        if (damage_qi > 0)
        {
            opp.ReceiveDamageKee(damage_qi, me);
            opp.ReceiveWoundKee(damage_qi / 2, me);
            ReportStatusKee(opp);
        }
        if (damage_shen > 0)
        {
            opp.ReceiveDamageSen(damage_shen, me);
            opp.ReceiveWoundSen(damage_shen / 2, me);
            ReportStatusSen(opp);
        }
    }
}
